某客户 5TB RAC 恢复小记
某客户的核心数据库存储问题导致数据库重启后无法正常启动,根据客户反馈最开始在启动数据库时报错控制文件 IO 错误,如下:
上述的问题本质上都跟控制文件有关系,替换掉损坏的控制文件就行。当替换掉控制文件之后,在 open 数据库时发现报如下错误:
该错误本质上是因为 redo 的问题,即有 redo log 损坏。通过在 RMAN 进行 recover,发现报如下类似错误:
上述过程大致是客户之前的处理过程。我在18点左右介入之后,进行了相关的操作。我最开始尝试在利用 RMAN 进行恢复,发现报错:
从上面的错误来看,初步可以判断 redo04a.log 文件已经损坏,而且是 block 1788672 的问题。为了验证该 block 是否损坏,我通过类似如下的 dump 命令进行 dump,发现报错:
由此判断,该 block 损坏无疑。 由于客户的需求是尽可能快的将数据库拉起来,因此对应 redo 损坏的情况之下。
通常只能进程不完全恢复并强制打开,这里我使用了如下的参数:
在 open resetlogs 之前,我已经将 redo 备份,resetlogs 打开时,发现数据库报错如下:
从日志来看,大致判断可能是_SYSSMU25$ 回滚段的问题,因此尝试先通过如下隐含参数屏蔽回滚段:
屏蔽回滚段之后,尝试打开数据库,发现错误依旧,通过10046 trace 跟踪,发现递归 SQL 在如下的 block 上执行失败:
通过 dump file 1 block 91,发现该 block 上第2个 ITL 确认存在一个活跃事务。原本计划直接 bbed 提交该事务,但是当我编译好 bbed 之后,查看发现该 block 为一个 cluster block.
对于 cluster block 的事务修改,相对复杂一些,我的博客有文章描述,大家可以参考,这里不多说。考虑到生产库使用 bbed 有一定的风险,我并没有使用 bbed。
接着使用 undo_management 参数启动数据库,然后强制 open 数据库,发现错误变成如下:
从错误来看,我们就可以知道,这应该是 SCN 的问题。如果要手工推进 SCN,那么 level 应该待遇3297*4才行,由于这里的 238091117/1024/1024/1024 小于1,因此推进 scn 时,level=3297*4+2 就差不多了。 这里我再次进行了10046 trace,发现了如下信息:
bscn: 0xce1.e379b05 将该 scn 进行转换,我们可以发现: 0xce1 为 3297,e379b05 为 238525189. 与上述报错信息一致。同时我发现这里使用了第2号回滚段,如下:
因此,尝试继续使用隐含参数屏蔽这第2号回滚段,并尝试打开数据库,但是错误依旧。看来还是需要调整 SCN 才行,如下:
首先我尝试了在会话级别设置:
发现 alter database open 失败,尝试使用*._minimum_giga_scn 参数,但是在启动的时候,提示说该参数不支持。从此判断,该环境可能是安装了比较新的 PSU,Oracle 将该参数废弃掉了,这么说前面的10015 event 根本就没起作用。 无奈只能通过 oradebug 手工修改 SCN 来启动数据库了,如下:
修改 SCN 之后,顺利打开了数据库,但是数据库很快就 crash 掉,如下是日志信息:
从上述日志信息来看,主要出现了如下几个错误:
ORA-00600 [6006],ORA-00600 [4137],ORA-00600 [kdsgrp1]
对于前面2个错误,很明显是 Oracle SMON 进程在进行利用回滚段进行事务 rollback 时失败导致,如下:
ORACLE Instance xxxx2 (pid = 22) – Error 600 encountered while recovering transaction (44, 26) on object 47098.
ORACLE Instance xxxx2 (pid = 22) – Error 600 encountered while recovering transaction (48, 25).
因此,不难看出,数据库中还有部分的回滚段存在活跃事务。
对于 ORA-00600 [kdsgrp1] 错误,通常是出现在 Index 上,即 Index 数据和表的数据不一致,一般来说可以通过重建解决。
其次,对于后面的 ORA-08102: index key not found, obj# 239, file 1, block 1674 (2) 错误,主要是 job 调用出现,因此我们可以暂时屏蔽 job 的调度。
对于 ORA-08102 错误,我的博客几年前也写过相关的文章,本质上也是 Index block 中的相关键值不存在导致。与其如此,最后我感觉将数据库的所有回滚段都屏蔽掉,并重建数据库 undo 表空间,如下是获取回滚段的命令:
strings system01.dbf | grep _SYSSMU | cut -d $ -f 1 | sort -u
经过整理,发现该库存在大约2600个回滚段,我了个去,先不管这么多,重启实例后,重建 undo 表空间:
最后重启数据库实例,让客户将关键核心的配置表导出,先进行业务恢复,如果需要数据,直接从库中抽取。
这里要补充一点,该库约为5TB 多一点,虽然有备份,但是恢复时间太长,如果有个 dataguard 是多么的重要啊!
------The End
文章来源:【love wife & love life —Roger 的 Oracle 技术博客】
配图来源:http://www.security-faqs.com/usb-data-recovery-loss-prevention-tips.html
2015 Oracle 技术嘉年华10月7日前五折门票抢购进行中,长按上方图片识别二维码注册参会!